package questions;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.ReentrantReadWriteLock;

/**
 * 共享锁-->允许多线程共享，但是只能共享读
 * 读可以有多个，写只能有一个
 *    RR √
 *    RW X
 *    WW X
 */
public class ReadAndWriteLockDemo {

    public static void main(String[] args) {
        Cache cache = new Cache();
        for (int i = 0; i < 10; i++) {
            new Thread(() -> {
                cache.set(Thread.currentThread().getName(), "值" + Thread.currentThread().getName());
            }, "t" + i).start();
        }
        for (int i = 0; i < 10; i++) {
            new Thread(() -> {
                cache.get(Thread.currentThread().getName());
            }, "t" + i).start();
        }
    }
}

class Cache{
    volatile Map<String, Object> map = new HashMap<>();
    ReentrantReadWriteLock reentrantReadWriteLock = new ReentrantReadWriteLock();

    public void set(String key, Object val) {
        reentrantReadWriteLock.writeLock().lock();
        System.out.println(Thread.currentThread().getName() + " 正在写入");
        map.put(key, val);
        try {
            TimeUnit.MILLISECONDS.sleep(400);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(Thread.currentThread().getName() + " 写入完成");
        reentrantReadWriteLock.writeLock().unlock();
    }

    public void get(String key) {
        reentrantReadWriteLock.readLock().lock();
        System.out.println(Thread.currentThread().getName() + " 正在获取");
        Object val = map.get(key);
        System.out.println(Thread.currentThread().getName() + " 获取成功" + val);
        reentrantReadWriteLock.readLock().unlock();
    }
}
